/*!\file libcytovision.h
 * Major include file
 * Include file with all functions and structures definition. Its necessary to any use of library
*/
#include <dirent.h>
#include <stdint.h>
#include <sys/stat.h>
#include <arpa/inet.h>

/*! \brief Default case directory.

 Directory used by Cytovision to manipulate cases. It must be small enough to support
 frequently scans.
*/
#define CASESDIR "/data/cytovision/cases/"

/*! \brief Default directory for completed cases
 *
 * When a case is marked as "completed", it must be moved to this directory for
 * performance and stability purposes. When Cytovision have more than 2000 files,
 * it became more and more slowly and unstable.
*/
#define CASESCOMPLETEDDIR "/data/cytovision/casescomplete/"

#define CASEDETAIL "case.detail"
#define CASECOMPLETE "COMPLETE"
#define CASELOCK ".lock"
#define SLIDENAME ".NAME"
#define CELLNAME ".NAME"
#define CGHSTATUS "cgh.status"

#define MAXNUMCELLS 255
#define MAXNUMSLIDES 32

#define HEADER_METAPHASE 0xcedadefa
#define HEADER_KARYOTYPE 0xedadefac
#define HEADER_PROBE 0x0b000300
#define HEADER_FLEX 0xedfedabe
//#define HEADER_FLEX 0xedabedfe

#ifndef DEBUGLEVEL
#define DEBUGLEVEL 9
#endif

extern int cytovision_scancases(char *path,void func(char *path,struct dirent *));
extern struct st_caseinfo *cytovision_open_case(char *path,char *casenum);
extern void cytovision_close_case(struct st_caseinfo *caseinfo);
extern int cytovision_check_security(char *s);
extern void cytovision_debug(int level, char *str, ...);
extern int cytovision_bmp2raw(char *filename_src, char *filename_dst);

/*! \brief Structure with all information about the case
*/
struct st_caseinfo {
  DIR *fdcasedir;  //!< FD to case directory
  char *casedir;   //!< Full path to casename
  int casecorrupt; //!< Any file from the case has corrupted?

  int fdcasedetail;           //!< FD to case.detail file
  char casedetailnumitems;    //!< Number of case.defail items
  char *casedetailitems[256]; //!< Access to each item

  int fdcasecomplete;    //!< FD to COMPLETE file
  char *casecompletedir; //!< Full path to COMPLETE file
  char casecomplete;     //!< Case completed? (y/n)

  int fdlock;    //!< FD to .lock file
  char *lockdir; //!< Full path to .lock file
  int locked;    //!< The case has locked by you?

  int num_slides; //!< Total number of slides
  struct st_slide *slides[MAXNUMSLIDES]; //!< Access to each slide
};

/*! \brief Structure for each slide
*/
struct st_slide {
  DIR *fd;       //!< FD to slide dir
  char *dir;     //!< Full path to slide directory
  int  fdname;   //!< FD descriptor to .NAME file
  char *namedir; //!< Full path to .NAME file
  char name[32]; //!< Name of slide
  int num_cells; //!< Number of cells found on this slide
  struct st_cell *cells[MAXNUMCELLS]; //!< Access to each cell
};

/*! \brief Structure for each cell
*/
struct st_cell {
  DIR *fd;            //!< FD to cell dir
  char *dir;          //!< Full path to cell directory
  int  fdname;        //!< FD descriptor to .NAME file
  int  fdcghstatus;   //!< FD descriptor to cgh.status file
  char name[32];      //!< Name of slide
  int num_imgs;       //!< Number of images
  struct st_img *img[32]; //!< Access to cell image
};

/*! \brief Structure for images
*/
struct st_img {
  int fd;
  char *name;        //!< Name of image
  char *ext;         //!< Extension
  struct stat st;    //!< Stat information
  struct st_img_data *data;
};

/*! \brief Data from images
*/
struct st_img_data {
  uint8_t  header[4];  //!< Signature CE DA DE FA (metaphase)
  uint8_t  ukn[7];
  uint16_t obj_count;  //!< Number of objects on image
  uint16_t obj_count2; //!< Number of objects on image
  uint8_t  mask[523];  //!< Enabled/Disabled objects
  uint8_t  ukn2;
} __attribute__((__packed__));
